package util;

/**
 * 算法工具类
 *
 * @author Europa
 * @create 2020-04-30 22:18
 */
public final class Utils {

    /**
     * 等差数列<br/>
     * 如果a1和q都为整数型可将结果强转为整数型
     *
     * @param a1 数列的第一个值
     * @param n  数量(必须为正整数)
     * @param d  公差
     * @return 前n项和
     */
    public static double apByTolerance(double a1, long n, double d) {
        if (n < 1) {
            throw new IllegalArgumentException("n必须为正整数: n = " + n);
        }
        return a1 * n + (n * (n - 1) * d) / 2;
    }

    /**
     * 等差数列<br/>
     * 如果a1和an都为整数型可将结果强转为整数型
     *
     * @param a1 数列第一个值
     * @param an 数列第n个值
     * @param n  数量(必须为正整数)
     * @return a1-an的和
     */
    public static double apByN(double a1, double an, long n) {
        if (n < 1) {
            throw new IllegalArgumentException("n必须为正整数: n = " + n);
        }
        return (n * (a1 + an)) / 2;
    }

    /**
     * 等差数列第n项<br/>
     * 如果a1和q都为整数型可将结果强转为整数型
     *
     * @param a1 数列的第一个值
     * @param n  数量(必须为正整数)
     * @param d  公差
     * @return 第n项的值
     */
    public static double apGeneralFormulas(double a1, long n, double d) {
        if (n < 1) {
            throw new IllegalArgumentException("n必须为正整数: n = " + n);
        }
        if (d == 0) {
            return a1 * n;
        }
        return a1 + (n - 1) * d;
    }

    /**
     * 等比数列<br/>
     * 如果a1和q都为整数型可将结果强转为整数型
     *
     * @param a1 数列第一个值(不能为0)
     * @param n  数列(必须为正整数)
     * @param q  公比(不能为0)
     * @return 前n项和的值
     */
    public static double geometricProgression(double a1, long n, double q) {
        if (q == 0 || n < 1 || a1 == 0) {
            throw new IllegalArgumentException("a1、q不能为0且n必须为正整数: a1 = " + a1 + ", n = " + n + ", q = " + q);
        } else if (q == 1) {
            return n * a1;
        } else {
            return (a1 * (1 - Math.pow(q, n))) / 1 - q;
        }
    }

}
